#pragma once 

#include <pthread.h>
#include <string>
#include <functional>
#include <iostream>



//  v3 线程池使用版本，在v1上做改版

namespace ThreadMouble
{
    // 原子计数器，方便给线程形成name
    uint32_t cnt=1;
    // 线程要执行的外部方法我们不考虑穿参，后续有std::bind来进行类间耦合
    //functino<返回值(参数类型，参数类型..)
    using  threadfunc_t=std::function<void(std::string name)>;

    //  线程状态
    enum class ThreadStatus
    {
        THREAD_NEW,
        THREAD_RUNNING,
        THREAD_STOP
    };

    // 线程
    class Thread
    {
        private:
            void SetNameAndId()
            {
                //后期加锁保护
                _name="thread-"+std::to_string(cnt++);
            }
            void EnableDetach()
            {
                if(_status==ThreadStatus::THREAD_NEW)
                    _joined=false;
            }
            // static修饰之后，可以直接调用不需要对象调用，但是实现中没有this指针
            static void* run(void* obj)
            {
                Thread* self=static_cast<Thread*>(obj);
                // ptrhead_setname_np  用于设置线程名称，一般不超过16个字符
            //    pthread_setname_np(self->_id,self->_name.c_str());    /// 可以设置也可以不设置

                self->_status=ThreadStatus::THREAD_RUNNING;
                if(!self->_joined)
                {
                    pthread_detach(self->_id);
                }
                self->_func(self->_name);
                return nullptr;
            }

        public:
            Thread(threadfunc_t func)
            : _status(ThreadStatus::THREAD_NEW)
            , _joined(true)
            ,_func(func)
            {
                SetNameAndId();
            }
            ~Thread(){}

            bool Start()
            {
                if(_status==ThreadStatus::THREAD_RUNNING) return false;
                int n=::pthread_create(&_id,nullptr,run,this);
                if(n!=0)
                    return false;
                return true; 
            }
            bool Stop()
            {
                if(_status==ThreadStatus::THREAD_RUNNING)
                {
                    int n=::pthread_cancel(_id);
                    if(n!=0)
                        return false;
                    _status=ThreadStatus::THREAD_STOP;
                    return true;
                } 
                return false;
            }
            bool Join()
            {
                if(_joined)
                {
                    int n=pthread_join(_id,nullptr);
                    if(n!=0) return false;
                    _status=ThreadStatus::THREAD_STOP;

                    return true;
                }
                return false;
            }
            void Detach()
            {
                EnableDetach();
                pthread_detach(_id);
            }
            std::string Name() {return _name;}
            bool GetJoin() {return _joined;}

        private:
            std::string _name;      //线程名称
            pthread_t _id;          // 线程id
            ThreadStatus _status;    // 线程状态
            bool _joined;           // 线程是否可回收
            threadfunc_t _func;     // 线程执行的程序 
    };
}


// // v2 模版封装传参版本
// namespace ThreadMouble
// {
//     // 原子计数器，方便给线程形成name
//     std::uint32_t cnt=1;
//     // 线程要执行的外部方法我们不考虑穿参，后续有std::bind来进行类间耦合
//     //functino<返回值(参数类型，参数类型..)

//     //  线程状态
//     enum class ThreadStatus
//     {
//         THREAD_NEW,
//         THREAD_RUNNING,
//         THREAD_STOP
//     };

//     // 线程
// template<class T>
//     class Thread
//     {
//         private:
//           using  threadfunc_t=std::function<void(T)>;

//             void SetNameAndId()
//             {
//                 //后期加锁保护
//                 _name="thread-"+std::to_string(cnt++);
//             }
//             void EnableDetach()
//             {
//                     _joined=false;
//             }
//             // static修饰之后，可以直接调用不需要对象调用，但是实现中没有this指针
//             static void* run(void* obj)
//             {
//                 Thread<T>* self=static_cast<Thread<T>*>(obj);
//                 // ptrhead_setname_np  用于设置线程名称，一般不超过16个字符
//                 pthread_setname_np(self->_id,self->_name.c_str());    /// 可以设置也可以不设置

//                 self->_status=ThreadStatus::THREAD_RUNNING;
//                 if(!self->_joined)
//                 {
//                     pthread_detach(self->_id);
//                 }
//                 self->_func(self->_data);
//                 return nullptr;
//             }

//         public:
//             Thread(threadfunc_t func, T data)
//             : _status(ThreadStatus::THREAD_NEW)
//             , _joined(true)
//             ,_func(func)
//             ,_data(data)
//             {
//                 SetNameAndId();
//             }
//             ~Thread(){}

//             bool Start()
//             {
//                 if(_status==ThreadStatus::THREAD_RUNNING) return false;
//                 int n=::pthread_create(&_id,nullptr,run,this);
//                 if(n!=0)
//                     return false;
//                 return true; 
//             }
//             bool Stop()
//             {
//                 if(_status==ThreadStatus::THREAD_RUNNING)
//                 {
//                     int n=::pthread_cancel(_id);
//                     if(n!=0)
//                         return false;
//                     _status=ThreadStatus::THREAD_STOP;
//                     return true;
//                 } 
//                 return false;
//             }
//             bool Join()
//             {
//                 if(_joined)
//                 {
//                     int n=pthread_join(_id,nullptr);
//                     if(n!=0) return false;
//                     _status=ThreadStatus::THREAD_STOP;

//                     return true;
//                 }
//                 return false;
//             }
//             bool Detach()
//             {
//                 EnableDetach();
//                 pthread_detach(_id);
//             }

//         private:
//             std::string _name;      //线程名称
//             pthread_t _id;          // 线程id
//             ThreadStatus _status;    // 线程状态
//             bool _joined;           // 线程是否可回收
//             threadfunc_t _func;     // 线程执行的程序 
//             T data;    // 外部方法使用的参数
//     };
// }


//  v1原始外部不传参通用版本

// namespace ThreadMouble
// {
//     // 原子计数器，方便给线程形成name
//     std::uint32_t cnt=1;
//     // 线程要执行的外部方法我们不考虑穿参，后续有std::bind来进行类间耦合
//     //functino<返回值(参数类型，参数类型..)
//     using  threadfunc_t=std::function<void()>;

//     //  线程状态
//     enum class ThreadStatus
//     {
//         THREAD_NEW,
//         THREAD_RUNNING,
//         THREAD_STOP
//     };

//     // 线程
//     class Thread
//     {
//         private:
//             void SetNameAndId()
//             {
//                 //后期加锁保护
//                 _name="thread-"+std::to_string(cnt++);
//             }
//             void EnableDetach()
//             {
//                 if(_status==ThreadStatus::THREAD_NEW)
//                     _joined=false;
//             }
//             // static修饰之后，可以直接调用不需要对象调用，但是实现中没有this指针
//             static void* run(void* obj)
//             {
//                 Thread* self=static_cast<Thread*>(obj);
//                 // ptrhead_setname_np  用于设置线程名称，一般不超过16个字符
//                 pthread_setname_np(self->_id,self->_name.c_str());    /// 可以设置也可以不设置

//                 self->_status=ThreadStatus::THREAD_RUNNING;
//                 if(!self->_joined)
//                 {
//                     pthread_detach(self->_id);
//                 }
//                 self->_func();
//                 return nullptr;
//             }

//         public:
//             Thread(threadfunc_t func)
//             : _status(ThreadStatus::THREAD_NEW)
//             , _joined(true)
//             ,_func(func)
//             {
//                 SetNameAndId();
//             }
//             ~Thread(){}

//             bool Start()
//             {
//                 if(_status==ThreadStatus::THREAD_RUNNING) return false;
//                 int n=::pthread_create(&_id,nullptr,run,this);
//                 if(n!=0)
//                     return false;
//                 return true; 
//             }
//             bool Stop()
//             {
//                 if(_status==ThreadStatus::THREAD_RUNNING)
//                 {
//                     int n=::pthread_cancel(_id);
//                     if(n!=0)
//                         return false;
//                     _status=ThreadStatus::THREAD_STOP;
//                     return true;
//                 } 
//                 return false;
//             }
//             bool Join()
//             {
//                 if(_joined)
//                 {
//                     int n=pthread_join(_id,nullptr);
//                     if(n!=0) return false;
//                     _status=ThreadStatus::THREAD_STOP;

//                     return true;
//                 }
//                 return false;
//             }
//             bool Detach()
//             {
//                 EnableDetach();
//                 pthread_detach(_id);
//             }


//         private:
//             std::string _name;      //线程名称
//             pthread_t _id;          // 线程id
//             ThreadStatus _status;    // 线程状态
//             bool _joined;           // 线程是否可回收
//             threadfunc_t _func;     // 线程执行的程序 
//     };
// }